<template>
  <div
    class="input-box border border-gray-200 rounded-md p-3 duration-300 relative"
    :class="{ focus }"
  >
    <div
      ref="edit-wrapper"
      contenteditable="true"
      :placeholder="$t('comment.placeholder')"
      class="edit-wrapper"
      @input="changeContent"
      @paste="changeContent"
      @focus="handleFocus"
      @blur="handleBlur"
    ></div>
    <div v-if="selectFile.file" class="relative inline-flex">
      <div
        class="text-sm text-gray-400 absolute p-1 top-0 right-0 hover:text-gray-600 duration-300 cursor-pointer"
        @click="deleteFile"
      >
        <svg-icon icon-class="guanbi"></svg-icon>
      </div>
      <img
        :src="selectFile.url"
        alt=""
        class="w-[50px] h-auto max-h-[100px] border-none"
      />
    </div>
    <div class="flex items-center justify-between pt-3">
      <div class="flex items-center gap-x-3">
        <div class="text-[20px] text-gray-500 relative">
          <div ref="emoji-svg">
            <svg-icon icon-class="emoji"></svg-icon>
          </div>
          <!-- emoji区域 -->
          <div v-show="emojiVisible" ref="emoji-wrapper" class="absolute z-30">
            <Card class="bg-white">
              <div class="w-[360px] max-h-[150px] overflow-y-auto">
                <ul class="flex flex-wrap gap-1">
                  <li
                    v-for="emoji in EMOJIS"
                    :key="emoji"
                    class="text-[18px] cursor-pointer"
                    @click="selectEmojo(emoji)"
                  >
                    <div>{{ emoji }}</div>
                  </li>
                </ul>
              </div>
            </Card>
          </div>
        </div>
        <div class="text-[20px] text-gray-500 relative">
          <input
            type="file"
            accept="image/*"
            class="absolute inset-0 opacity-0"
            @input="handlerInput"
          />
          <svg-icon icon-class="picture"></svg-icon>
        </div>
      </div>
      <div class="flex items-center">
        <div class="mr-3" :class="{ danger: !vailid }">
          {{ length }}/{{ maxLength }}
        </div>
        <button
          class="px-3 py-1 bg-[#00c4b6] text-white rounded-sm disabled:opacity-50 disabled:select-none duration-300"
          :disabled="!vailid"
          @click="handleSendComment"
        >
          {{ $t('comment.send') }}
        </button>
      </div>
    </div>

    <div
      v-if="!userInfo"
      class="mask absolute inset-0 bg-white bg-opacity-70 rounded-md cursor-not-allowed flex items-center justify-center"
    >
      <p class="text-[#8BC34A]">请先点击上方的授权登录后再进行评论~~</p>
    </div>
  </div>
</template>
<script>
import { EMOJIS } from '@/constants'
import { isSameNode, getElementTextLength } from '~/utils'
export default {
  data() {
    return {
      EMOJIS,
      emojiVisible: false,
      content: '',
      length: 0,
      maxLength: 500,
      selectFile: {
        url: '',
        file: null,
      },
      focus: false, // 是否获取焦点？
    }
  },
  computed: {
    // 校验结果
    vailid() {
      return this.length <= this.maxLength
    },
    userInfo() {
      return this.$store.state.userInfo
    },
  },
  mounted() {
    const handleClick = (e) => {
      if (this.emojiVisible) {
        if (!isSameNode(this.$refs['emoji-wrapper'], e.target)) {
          this.emojiVisible = false
        }
      } else if (isSameNode(this.$refs['emoji-svg'], e.target)) {
        this.emojiVisible = true
      }
    }
    document.addEventListener('click', handleClick)
    this.$on('hook:beforeDestory', () => {
      document.removeEventListener('click', handleClick)
    })
  },
  methods: {
    // 检测div中的内容长度
    checkLength(el) {
      //   const innerHTML = el.innerHTML
      //   if (innerHTML.length > this.maxLength) {
      //     el.innerHTML = el.innerHTML.slice(0, this.maxLength)
      //     // this.textFocus()
      //   }
      //   this.length = el.innerHTML.length
      //   this.length = Array.from(el.childNodes).reduce((acc, one) => {
      //     if (one.nodeType === 1) {
      //       // 元素节点
      //       acc += 1
      //     } else {
      //       // 文本节点
      //       acc += one.length
      //     }
      //     return acc
      //   }, 0)
      this.length = getElementTextLength(el)
    },
    // 文本输入框聚焦，焦点在最后位置
    textFocus() {
      setTimeout(() => {
        this.$refs['edit-wrapper'].focus()
        document.execCommand('selectAll', false, null)
        document.getSelection().collapseToEnd()
      }, 0)
    },
    handlerInput(e) {
      const file = e.target.files[0]
      this.selectFile.file = file
      e.target.value = ''
      const reader = new FileReader()
      reader.readAsDataURL(file)
      reader.onload = (e) => {
        this.selectFile.url = e.target.result
      }
    },
    deleteFile() {
      this.selectFile = {
        url: '',
        file: null,
      }
    },
    selectEmojo(emoji) {
      const span = document.createElement('span')
      span.setAttribute('contenteditable', 'false')
      span.setAttribute('class', 'emoji-box')
      span.innerHTML = emoji
      this.$refs['edit-wrapper'].appendChild(span)
      this.checkLength(this.$refs['edit-wrapper'])
    },
    handleFocus() {
      this.focus = true
    },
    handleBlur() {
      this.focus = false
    },
    // 发送评论
    handleSendComment() {
      if (!this.vailid) return this.$message.warning('字数超过限制！')

      const data = {
        content: this.$refs['edit-wrapper'].innerHTML,
        file: this.selectFile.file,
      }
      this.$emit('onSubmit', data)
    },

    changeContent(e) {
      e.preventDefault() // 阻止默认粘贴行为
      this.setPlainText(e)
    },
    setPlainText(e) {
      // 父剪切板中获取内筒
      const text = e.clipboardData
        ? (e.originalEvent || e).clipboardData.getData('text/plain')
        : // For IE
        window.clipboardData
        ? window.clipboardData.getData('Text')
        : ''
      // 获取光标位置
      const range = document.getSelection().getRangeAt(0)
      range.deleteContents()
      // 创建文本节点
      const textNode = document.createTextNode(text)
      // 将文本节点插入到range
      range.insertNode(textNode)
      range.selectNodeContents(textNode)
      range.collapse(false)
      const selection = window.getSelection()
      selection.removeAllRanges()
      selection.addRange(range)
      // 计算内容长度
      this.checkLength(e.target)
    },
  },
}
</script>
<style lang="scss" scoped>
.input-box {
  &.focus {
    border-color: #00c4b6;
  }
}
.edit-wrapper {
  border: none;
  outline: none;
  line-height: 20px;
  min-height: 40px;
  transition: all 0.3s ease-in-out;
  &:empty {
    &::after {
      content: attr(placeholder);
      display: block;
      transition: all 0.3s ease-in-out;
    }
  }
  &:focus {
    min-height: 60px;
  }
}
.danger {
  color: #e91e63;
}
</style>
